"""
/* Copyright 2018 The Enflame Tech Company. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
"""
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import json
import socket
import psutil
import subprocess


class CPU:

    @classmethod
    def _get_cpu_load(cls):
        loadavg = "/proc/loadavg"
        with open(loadavg) as f:
            con = f.read().split()
            return con[1]

    @classmethod
    def _get_cpu_usage(cls):
        return psutil.cpu_percent(interval=0.1)

    @classmethod
    def get_cpu_info(cls):
        cpu = {
            "cpuUtil": cls._get_cpu_load(),
            "cpuUsed": cls._get_cpu_usage()
        }
        return cpu


class Memory:

    mem = psutil.virtual_memory()

    @classmethod
    def _get_mem_total(cls):
        return cls.mem.total

    @classmethod
    def _get_mem_used(cls):
        return cls.mem.used

    @classmethod
    def get_mem_info(cls):
        mem = {
            "memUsed": cls._get_mem_used(),
            "memTotal": cls._get_mem_total(),
        }
        return mem


class NetworkCard:

    @classmethod
    def get_card_bytes_info(cls):
        # bytes_sent
        try:
            card_ip = []
            card_io = []
            interface = []
            for k, v in psutil.net_if_addrs().items():
                if k not in 'lo':
                    card_ip.append({'name': k, 'ip':v[0].address})

            for k, v in psutil.net_io_counters(pernic=True).items():
                if k not in 'lo':
                    card_io.append({'name': k, 'out': v.bytes_sent, 'in': v.bytes_recv})

            for i in range(len(card_ip)):

                card = {
                    'intName': card_io[i]['name'],
                    'ip': card_ip[i]['ip'],
                    'out': card_io[i]['out'],
                    'in': card_io[i]['in']
                }
                interface.append(card)
            return interface
        except AttributeError as e:
            print("Please use psutil version 3.0 or above")


class Disk:

    @classmethod
    def get_disk_info(cls):
        disklt = []
        for disk, sdiskio in psutil.disk_io_counters(perdisk=True, nowrap=False).items():
            if disk.startswith(('sd','vd')):
                device = '/dev/{}'.format(disk)
                capacity = psutil.disk_usage(device)
                diskdt = {
                    "diskName": device,
                    "total": capacity.total,
                    "used": capacity.used,
                    "ws": sdiskio.write_merged_count,
                    "rs": sdiskio.read_merged_count,
                    "wiops": sdiskio.write_count,
                    "riops": sdiskio.read_count,
                    "rkb": sdiskio.read_bytes / 1024,
                    "wkb": sdiskio.write_bytes / 1024
                }
                disklt.append(diskdt)
        return disklt


class DTU:

    @classmethod
    def _get_dtu_mem_usage(cls):
        proc = subprocess.Popen(['cat /sys/kernel/debug/dtu/0/dump/dump_mem_usage'], stdout=subprocess.PIPE, shell=True )
        return proc.communicate()[0].strip()

    @classmethod
    def _get_dtu_cqm_status(cls):
        proc = subprocess.Popen(['cat /sys/kernel/debug/dtu/0/dump/dump_cqm_sts'], stdout=subprocess.PIPE, shell=True )
        return proc.communicate()[0].strip()

    @classmethod
    def _get_dtu_reg_status(cls):
        proc = subprocess.Popen(['cat /sys/kernel/debug/dtu/0/dump/dump_reg_sts'], stdout=subprocess.PIPE, shell=True )
        return proc.communicate()[0].strip()

    @classmethod
    def get_dtu_info(cls):
        dtudt = {
            "dtuUsed": cls._get_dtu_mem_usage(),
            "dtuCqm": cls._get_dtu_cqm_status(),
            "dtuReg": cls._get_dtu_reg_status()
        }


class Summary:

    @classmethod
    def collection(self):
        summary = {
            'cpu': CPU.get_cpu_info(),
            'memory': Memory.get_mem_info(),
            'network': NetworkCard.get_card_bytes_info(),
            'disk': Disk.get_disk_info(),
            'DTU': DTU.get_dtu_info()
        }
        return json.dumps(summary, indent=4, sort_keys=False)

if __name__ == '__main__':
    print(Summary.collection())
